/**
 * Created by luzd on 17/3/13.
 */
/**
 * Created by nuoxin on 16/10/8.
 */
var requestAnimationFrame = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    function (callback) {
        setTimeout(callback, 1000 / 60);
    };
var cancelAnimationFrame = window.cancelAnimationFrame ||
    window.mozCancelAnimationFrame ||
    window.webkitCancelAnimationFrame ||
    window.msCancelAnimationFrame ||
    window.oCancelAnimationFrame;

var canvas = document.querySelector('#canvas');
canvas.width = document.documentElement.clientWidth;
canvas.height = document.documentElement.clientHeight;

var game = new Game(canvas, {fallLength: 10, fallSpeed: 3, time: 45 * 1000});

function Game(can, o) {
    var self = this;
    self.can = can;
    self.w = can.width;
    self.h = can.height;
    self.status = 0;                    //0-初始化、1-开始、2-停止、3-暂停、4-继续
    self.loop = null;                   //动画
    self.bear = null;                   //小熊
    self.bearImg = null;                  //小熊图片
    self.falls = [];                   //坠落物，包括叶子和果子
    self.images = [];                      //坠落物图片
    self.fallLength = o.fallLength || 100;        //坠落物数量
    self.fallSpeed = o.fallSpeed;           //坠落速度
    self.time = o.time;                   //时长
    self.lastTime = self.time;              //游戏剩余时间
    self.score = 0;                        //得分
    self.disX = 500;                         //坠落物x坐标间距基数
    self.disY = 1;                         //坠落物y坐标间距
    self.loading = true;                    //是否在加载资源
    self.int = null;                         //倒计时
    self.audio = document.querySelector('audio');
    var context = can.getContext('2d');

    self.init = function () {
        self.status = 0;
        self.loop = null;
        self.int = null;
        self.bear = null;
        self.falls = [];
        self.lastTime = self.time;
        self.score = 0;
    };

    self.createBear = function () {
        if (self.bearImg) {
            self.bear = new Bear(self.bearImg, self.w, self.h);
        }
    };

    self.createFalls = function () {
        var falls = self.falls,
            images = self.images,
            len = images.length;
        for (var i = 0; i < self.fallLength; i++) {
            if (len) {
                var ran = parseInt(len * Math.random());
                falls.push(new Fall(images[ran].img, images[ran].type, self));
            }
        }
    };

    self.draw = function () {
        context.clearRect(0, 0, self.w, self.h);
        self.bear.render();
        for (var i = 0; i < self.fallLength; i++) {
            self.falls[i].update(self);
            self.falls[i].render();
        }
        self.loop = requestAnimationFrame(function () {
            self.draw();
        });
    };

    self.start = function () {
        if (self.status == 1 || self.status == 4) {
            return false;
        }
        self.status = 1;
        self.createBear();
        self.createFalls();
        self.draw();
        self.showTime();
        self.down();
        self.audio.play();
    };
    self.pause = function () {
        if (self.status == 1 || self.status == 4) {
            self.status = 3;
            cancelAnimationFrame(self.loop);
            clearInterval(self.int);
            self.audio.pause();
        }
    };
    self.resume = function () {
        if (self.status == 3) {
            self.status = 4;
            // 动画的计时控制
            self.loop = requestAnimationFrame(function () {
                self.draw();
            });
            self.down();
        }
    };
    self.stop = function () {
        if (this.status == 2) {
            return false;
        }
        self.pause();
        context.clearRect(0, 0, self.w, self.h);
        self.init();
    };
    self.success = function () {
        var score = self.score < 0 ? 0 : self.score;
        showResult(score);
        self.stop();
    };

    self.down = function () {
        self.int = setInterval(function () {
            self.lastTime -= 1000;
            if (self.lastTime <= 0) {
                clearInterval(self.int);
                self.success();
            }
            self.showTime();
        }, 1000);
    };
    self.showTime = function () {
        var m = Math.floor(self.lastTime / 1000 / 60 % 60) + '',
            s = Math.floor(self.lastTime / 1000 % 60) + '';
        m = m.length < 2 ? '0' + m : m;
        s = s.length < 2 ? '0' + s : s;
        $('#time').html(m + ':' + s);
    };
    self.can.addEventListener('touchstart', function (e) {
        var bear = self.bear;
        if (!bear) {
            return;
        }
        var touchMode = e.targetTouches,
            pointer;
        if (touchMode) {
            e.preventDefault();
            pointer = touchMode[0];
        } else pointer = e;
        var _x = pointer.clientX,
            _y = pointer.clientY;
        var cover = _x > bear.x + 20 && _x < bear.x + self.w - 20 && _y > bear.y + 20 && _y < bear.y + self.h - 20;
        if (cover) {
            bear.touched = true;
        }
        bear.dx = pointer.clientX - bear.x;
    }, false);
    self.can.addEventListener('touchmove', function (e) {
        var bear = self.bear;
        if (!bear) {
            return;
        }
        var touchMode = e.targetTouches,
            pointer;
        if (touchMode) {
            e.preventDefault();
            pointer = touchMode[0];
        } else pointer = e;
        bear.update(pointer, self);
    }, false);
    self.can.addEventListener('touchend', function () {
        var bear = self.bear;
        if (!bear) {
            return;
        }
        bear.dx = 0;
        bear.touched = false;
    }, false);

    /**
     * 小熊定义
     * @param img
     * @param w
     * @param h
     * @constructor
     */
    function Bear(img, w, h) {
        var _w = img.width / 2,
            _h = img.height / 2;
        this.img = img;
        this.w = _w;
        this.h = _h;
        this.x = (w - _w) / 2;
        this.y = h - _h;
        this.touched = false;
        this.dx = 0;                    //touchMove 手指触摸与x坐标距离
    }

    /**
     * touchmove更改小熊x坐标
     * this.dx保存的是toushstart时x坐标与触摸点间距
     * 当touchmove触摸点更改时，用更改量减去初始间距，得到x坐标位置
     * canvas根据x坐标重绘
     */
    Bear.prototype.update = function (pointer, game) {
        var _x = pointer.clientX,
            px;
        if (this.touched) {
            px = _x - this.dx;
            if (px > -this.w / 2 && px + this.w / 2 < game.w) {
                this.x = px;
            }
        }
    };
    /**
     * 绘制小熊
     */
    Bear.prototype.render = function () {
        context.drawImage(this.img, this.x, this.y, this.w, this.h);
    };

    function Fall(img, type, game) {
        var _w = img.width / 2,
            _h = img.height / 2;
        this.img = img;
        this.type = type;                                 //1 果子 2 叶子
        this.w = _w;
        this.h = _h;
        this.key = Math.random();
        this.x = Math.floor(Math.random() * game.w);	            //x坐标
        this.y = -Math.floor(Math.random() * game.h * game.disY);	    //y坐标
        this.speed = Math.random() + game.fallSpeed;			    //坠落速度
        this.fallSpeed = game.fallSpeed;							//坠落速度
        this.velY = this.speed;								//Y方向速度
        this.velX = 0;										//X方向速度
        this.stepSize = Math.random() / game.disX;					//步长
        this.step = 0; 										//步数
        this.showText = false;                                   //是否显示得分
        this.showX = 0;                                       //得分显示x坐标
        this.showY = 0;                                       //得分显示y坐标
        this.disY = game.disY;
        this.game = game;
    }

    Fall.prototype.update = function (game) {
        // 左右摆动(余弦)
        var self = this,
            bear = game.bear;

        this.velX *= 0.98;
        this.velX += Math.cos(this.step += .05) * this.stepSize;

        this.y += this.velY;
        this.x += this.velX;

        //判断是否得分
        var _left = bear.x + bear.w * .10,
            _right = bear.x + bear.w * .90,
            _top = bear.y + 20;

        if (this.x > _left && this.x + this.w < _right && this.y + this.h > _top && this.y < bear.y + this.h / 2) {
            this.type == 1 ? ++game.score : --game.score;
            this.showText = true;
            this.showX = this.x + this.w + 10;
            this.showY = this.y + 40 > bear.y ? this.y : bear.y - 30;
            this.x = Math.floor(Math.random() * game.w);	            //x坐标
            this.y = -Math.floor(Math.random() * game.h * this.disY);	//y坐标
            setTimeout(function () {
                self.showText = false;
                self.showX = 0;
                self.showY = 0;
            }, 500);
        }

        // 飞出边界的处理
        if (this.y + this.h >= game.h + Math.random() * 1000) {
            this.x = Math.floor(Math.random() * game.w);
            this.y = -Math.floor(Math.random() * game.h * this.disY);	//y坐标
            this.speed = Math.random() + this.fallSpeed;
            this.velY = this.speed;
            this.velX = 0;
        }
    };

    Fall.prototype.render = function () {
        context.drawImage(this.img, this.x, this.y, this.w, this.h);
        if (this.showText) {
            this.showScore();
        }
    };

    Fall.prototype.showScore = function () {
        var text = (this.type == 1 ? '+' : '-') + ' 1';
        context.font = 'bold 16px Arial';
        context.fillStyle = '#843a1f';
        var _w = context.measureText(text).width;
        if (_w + this.showX > this.game.w) {
            this.showX = this.game.w - _w;
        }
        context.fillText(text, this.showX, this.showY);
    };
}

/**
 * 图片加载方法
 * @param url
 * @param success
 * @param fail
 */
function loadImage(url, success, fail) {
    var img = new Image();
    img.onload = function () {
        img.onload = null;
        success(img, url);
    };
    img.onerror = function () {
        img.onerror = null;
        fail();
    };
    img.src = url;
}
/**
 * 显示游戏首页,隐藏加载进度
 */
function showGuide() {
    var progress = $('.progress');
    $('.guide').removeClass('hide');
    setTimeout(function () {
        progress.addClass('shadow');
    }, 300);
    setTimeout(function () {
        progress.remove();
    }, 900);
}
/**
 * 所有图片资源
 * 1,正常图片，2，掉落物图片，3，小熊
 */
var sourceLoading = {
    images: [
        {
            src: 'add.png',
            type: 1
        },
        {
            src: 'ball.png',
            type: 1
        },
        {
            src: 'bear.png',
            type: 3
        },
        {
            src: 'bg.jpg',
            type: 1
        },
        {
            src: 'dialog_bg.png',
            type: 1
        },
        {
            src: 'btn_rule.png',
            type: 1
        },
        {
            src: 'btn_start.png',
            type: 1
        },
        {
            src: 'fruit_1.png',
            type: 2
        },
        {
            src: 'fruit_2.png',
            type: 2
        },
        {
            src: 'fruit_3.png',
            type: 2
        },
        {
            src: 'demo_4.png',
            type: 1
        },
        {
            src: 'demo_5.png',
            type: 1
        },
        {
            src: 'demo_6.png',
            type: 1
        },
        {
            src: 'demo_bg_4.png',
            type: 1
        },
        {
            src: 'demo_bg_5.png',
            type: 1
        },
        {
            src: 'demo_bg_6.png',
            type: 1
        },
        {
            src: 'leaf_1.png',
            type: 2
        },
        {
            src: 'leaf_2.png',
            type: 2
        },
        {
            src: 'leaf_3.png',
            type: 2
        }
    ],
    fallImages: [],
    bearImg: null,
    successCount: 0,
    failCount: 0,
    int: 0,
    imgLink: '/mobile/topic/s2016/bear/assets/i/',
    init: function () {
        var self = this,
            len = self.images.length;
        self.images.forEach(function (v) {
            var src = self.imgLink + v.src;
            loadImage(src, function (img) {
                if (v.type == 2) {
                    self.fallImages.push({img: img, type: v.src.indexOf('fruit') !== -1 ? 1 : 2});
                }
                if (v.type == 3) {
                    self.bearImg = img;
                }
                self.successCount++;
                self.int = parseInt(self.successCount / len * 100, 10);
                self.int = self.int > 10 ? self.int : 10;
                $('.inner i').css({
                    width: self.int + '%'
                });
                self.checkProcess();
            }, function () {
                self.failCount++;
                self.checkProcess();
            });
        });
    },
    checkProcess: function () {
        if (this.successCount + this.failCount >= this.images.length) {
            showGuide();
            setGameInfo();
        }
    }
};
/**
 * 设置游戏小熊图片对象，游戏掉落物图片对象
 */
function setGameInfo() {
    game.bearImg = sourceLoading.bearImg;
    sourceLoading.fallImages.forEach(function (item) {
        game.images.push({img: item.img, type: item.type});
    });
}

$(function () {
    /**
     * 加载图片，显示进度条
     */
    sourceLoading.init();
    /**
     * 禁止触摸事件
     */
    $('.no_touch').each(function () {
        var item = $(this)[0];
        item.addEventListener('touchmove', function (e) {
            e.preventDefault();
        }, false);
    });
});